package com.ruoyi.web.controller.system;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.businessOrder.domain.BusinessOrder;
import com.ruoyi.businessOrder.service.IBusinessOrderService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.order.domain.Order;
import com.ruoyi.order.service.IOrderService;
import com.ruoyi.web.controller.system.dto.WxPayV3CallbackDTO;
import com.ruoyi.web.controller.system.util.WxPayV3CallbackUtil;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信支付回调控制器
 * 处理微信支付成功后的回调通知
 *
 * @author ruoyi
 * @date 2025-11-05
 */
@RestController
@RequestMapping("/wxpay")
public class WxPayCallbackController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(WxPayCallbackController.class);

    @Autowired
    private IBusinessOrderService businessOrderService;

    @Autowired
    private IOrderService orderService;

    @Value("${wxpayment.api_v3_key:}")
    private String apiV3Key;

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 微信支付回调通知
     * 路径：/wxpay/pay
     *
     * @param requestBody 微信支付回调的请求体
     * @param request HttpServletRequest对象
     * @return 微信支付要求的响应格式
     */
    @PostMapping("/pay")
    public String payCallback(@RequestBody(required = false) String requestBody, HttpServletRequest request) {
        try {
            log.info("收到微信支付回调通知，请求体: {}", requestBody);

            // 1. 验证请求体
            if (StringUtils.isEmpty(requestBody)) {
                log.error("微信支付回调请求体为空");
                return buildErrorResponse("FAIL", "请求体为空");
            }

            // 2. 解析回调数据（这里简化处理，实际需要验证签名等）
            // 在实际项目中，这里需要验证微信回调的签名，确保请求的合法性
            Map<String, String> callbackData = parseCallbackData(requestBody);

            if (callbackData == null) {
                log.error("解析微信支付回调数据失败");
                return buildErrorResponse("FAIL", "数据解析失败");
            }

            // 3. 获取订单信息
            String outTradeNo = callbackData.get("out_trade_no");
            String transactionId = callbackData.get("transaction_id");
            String tradeState = callbackData.get("trade_state");

            if (StringUtils.isEmpty(outTradeNo)) {
                log.error("微信支付回调缺少订单号");
                return buildErrorResponse("FAIL", "缺少订单号");
            }

            // 4. 验证支付状态
            if (!"SUCCESS".equals(tradeState)) {
                log.warn("微信支付回调状态非成功状态: {}, 订单号: {}", tradeState, outTradeNo);
                return buildErrorResponse("FAIL", "支付状态异常");
            }

            log.info("微信支付回调成功，订单号: {}, 微信交易号: {}", outTradeNo, transactionId);

            // 5. 根据订单号查询订单ID
            Long orderId = getOrderIdByOrderCode(outTradeNo);
            if (orderId == null) {
                log.error("根据订单号未找到对应订单，订单号: {}", outTradeNo);
                return buildErrorResponse("FAIL", "订单不存在");
            }

            // 6. 处理支付成功逻辑
            try {
//                businessOrderService.handlePaymentSuccess(orderId);
                log.info("支付成功处理完成，订单ID: {}", orderId);
            } catch (Exception e) {
                log.error("处理支付成功逻辑时发生异常，订单ID: {}", orderId, e);
                return buildErrorResponse("FAIL", "处理支付成功逻辑失败");
            }

            // 7. 返回成功响应（微信要求返回success）
            return buildSuccessResponse();

        } catch (Exception e) {
            log.error("微信支付回调处理异常", e);
            return buildErrorResponse("FAIL", "系统异常");
        }
    }

    /**
     * 构建成功响应
     * 微信支付要求返回"success"字符串
     */
    private String buildSuccessResponse() {
        return "success";
    }

    /**
     * 构建错误响应
     */
    private String buildErrorResponse(String code, String message) {
        // 微信支付回调要求返回特定格式，这里简化处理
        // 实际应该根据微信文档返回正确的XML格式
        return "FAIL";
    }

    /**
     * 解析回调数据
     * 解析微信支付回调的XML格式数据
     */
    private Map<String, String> parseCallbackData(String requestBody) {
        try {
            if (StringUtils.isEmpty(requestBody)) {
                return null;
            }

            Map<String, String> result = new HashMap<>();

            // 使用dom4j解析XML
            Document document = DocumentHelper.parseText(requestBody);
            Element root = document.getRootElement();

            // 遍历所有子节点
            List<Element> elements = root.elements();
            for (Element element : elements) {
                result.put(element.getName(), element.getTextTrim());
            }

            log.debug("解析微信回调数据成功: {}", result);
            return result;

        } catch (Exception e) {
            log.error("解析微信支付回调数据异常", e);
            return null;
        }
    }

    /**
     * 根据订单号获取订单ID
     */
    private Long getOrderIdByOrderCode(String orderCode) {
        try {
            // 尝试从业务订单中查找
            BusinessOrder businessOrder = businessOrderService.getByOrderCode(orderCode);
            if (businessOrder != null) {
                return businessOrder.getOrderId();
            }

            // 如果业务订单中没找到，尝试从商品订单中查找
            Order order = orderService.getByOrderCode(orderCode);
            if (order != null) {
                return order.getOrderId();
            }

            return null;
        } catch (Exception e) {
            log.error("根据订单号查询订单ID异常，订单号: {}", orderCode, e);
            return null;
        }
    }

    /**
     * 微信退款回调通知
     * 路径：/wxpay/refund
     */
    @PostMapping("/refund")
    public String refundCallback(@RequestBody(required = false) String requestBody, HttpServletRequest request) {
        try {
            log.info("收到微信退款回调通知，请求体: {}", requestBody);

            // 退款回调处理逻辑（这里简化实现）
            // 实际项目中需要验证签名、解析数据、更新退款状态等

            return buildSuccessResponse();
        } catch (Exception e) {
            log.error("微信退款回调处理异常", e);
            return buildErrorResponse("FAIL", "系统异常");
        }
    }

    /**
     * 微信支付V3版本回调通知
     * 路径：/wxpay/v3/pay
     *
     * @param callbackData V3回调数据
     * @param request HttpServletRequest对象
     * @return 返回204状态码表示成功
     */
    @PostMapping("/v3/pay")
    public ResponseEntity<String> payCallbackV3(@RequestBody WxPayV3CallbackDTO callbackData, HttpServletRequest request) {
        try {
            log.info("收到微信支付V3回调通知，事件类型: {}", callbackData.getEventType());

            // 1. 验证回调数据
            if (callbackData == null || callbackData.getResource() == null) {
                log.error("微信支付V3回调数据为空");
                return ResponseEntity.badRequest().build();
            }

            // 2. 验证事件类型
            if (!"TRANSACTION.SUCCESS".equals(callbackData.getEventType())) {
                log.warn("微信支付V3回调事件类型非支付成功: {}", callbackData.getEventType());
                return ResponseEntity.ok().build(); // V3版本对于非成功事件也返回成功
            }

            // 3. 验证签名（简化处理，实际项目需要完整实现）
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            String nonce = request.getHeader("Wechatpay-Nonce");
            String signature = request.getHeader("Wechatpay-Signature");

            if (!WxPayV3CallbackUtil.verifySignature(timestamp, nonce, signature, objectMapper.writeValueAsString(callbackData))) {
                log.error("微信支付V3回调签名验证失败");
                return ResponseEntity.badRequest().build();
            }

            // 4. 解密回调数据
            Map<String, Object> decryptedData = WxPayV3CallbackUtil.decryptCallbackData(callbackData, apiV3Key);
            log.info("解密后的微信支付V3回调数据: {}", decryptedData);

            // 5. 提取订单信息
            String outTradeNo = (String) decryptedData.get("out_trade_no");
            String transactionId = (String) decryptedData.get("transaction_id");
            String tradeState = (String) decryptedData.get("trade_state");
            String successTime = (String) decryptedData.get("success_time");

            if (StringUtils.isEmpty(outTradeNo)) {
                log.error("微信支付V3回调缺少订单号");
                return ResponseEntity.badRequest().build();
            }

            // 6. 验证支付状态
            if (!"SUCCESS".equals(tradeState)) {
                log.warn("微信支付V3回调状态非成功状态: {}, 订单号: {}", tradeState, outTradeNo);
                return ResponseEntity.ok().build(); // V3版本对于非成功状态也返回成功
            }

            log.info("微信支付V3回调成功，订单号: {}, 微信交易号: {}", outTradeNo, transactionId);

            // 7. 根据订单号查询订单ID
            Long orderId = getOrderIdByOrderCode(outTradeNo);
            if (orderId == null) {
                log.error("根据订单号未找到对应订单，订单号: {}", outTradeNo);
                return ResponseEntity.ok().build(); // V3版本对于订单不存在也返回成功
            }

            // 8. 处理支付成功逻辑
            try {
                // 调用订单服务更新订单状态
                boolean updateResult = orderService.updateOrderStatus(outTradeNo, transactionId, successTime);
                if (updateResult) {
                    log.info("V3支付成功处理完成，订单ID: {}", orderId);
                } else {
                    log.error("V3支付成功处理失败，订单ID: {}", orderId);
                }
            } catch (Exception e) {
                log.error("处理V3支付成功逻辑时发生异常，订单ID: {}", orderId, e);
                // V3版本即使处理失败也返回成功，避免微信重复回调
            }

            // 9. 返回成功响应（V3版本返回204状态码）
            return ResponseEntity.status(HttpStatus.NO_CONTENT).build();

        } catch (Exception e) {
            log.error("微信支付V3回调处理异常", e);
            // V3版本即使异常也返回成功，避免微信重复回调
            return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
        }
    }

    /**
     * 微信支付V3版本退款回调通知
     * 路径：/wxpay/v3/refund
     */
    @PostMapping("/v3/refund")
    public ResponseEntity<String> refundCallbackV3(@RequestBody WxPayV3CallbackDTO callbackData, HttpServletRequest request) {
        try {
            log.info("收到微信支付V3退款回调通知，事件类型: {}", callbackData.getEventType());

            // V3退款回调处理逻辑（这里简化实现）
            // 实际项目中需要验证签名、解密数据、更新退款状态等

            // 返回成功响应（V3版本返回204状态码）
            return ResponseEntity.status(HttpStatus.NO_CONTENT).build();

        } catch (Exception e) {
            log.error("微信支付V3退款回调处理异常", e);
            return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
        }
    }
}